﻿using MockDataAccess;
using MockDataTransferObject;
using System;
using System.Collections.Generic;
using MockCommon;
using System.Collections.ObjectModel;

namespace MockBusiness
{
    public class ContractorBusiness
    {
        #region Initialize
        private static ContractorBusiness _instance;
        private readonly UserDataAccess _userDataAccess;
        private readonly RoleDataAccess _roleDataAccess;
        private readonly ContractorDataAccess _contractorDataAccess;

        /// <summary>
        /// Gets the user data test.
        /// </summary>
        public Collection<User> UserDataTest
        {
            get
            {
                return _userDataAccess.AffectedRows;
            }
        }

        /// <summary>
        /// Gets the role data test.
        /// </summary>
        public Collection<Role> RoleDataTest
        {
            get
            {
                return _roleDataAccess.AffectedRows;
            }
        }

        /// <summary>
        /// Gets the contractor data test.
        /// </summary>
        public Collection<Contractor> ContractorDataTest
        {
            get
            {
                return _contractorDataAccess.AffectedRows;
            }
        }

        /// <summary>
        /// Prevents a default instance of the <see cref="ContractorBusiness"/> class from being created.
        /// </summary>
        private ContractorBusiness()
        {
            _userDataAccess = new UserDataAccess();
            _roleDataAccess = new RoleDataAccess();
            _contractorDataAccess = new ContractorDataAccess();
        }

        /// <summary>
        /// Prevents a default instance of the <see cref="ContractorBusiness"/> class from being created.
        /// </summary>
        /// <param name="isFake">if set to <c>true</c> [is fake].</param>
        private ContractorBusiness(bool isFake)
        {
            _userDataAccess = new UserDataAccess(isFake);
            _roleDataAccess = new RoleDataAccess(isFake);
            _contractorDataAccess = new ContractorDataAccess(isFake);
        }

        /// <summary>
        /// Retrieves the instance.
        /// </summary>
        /// <returns></returns>
        public static ContractorBusiness RetrieveInstance()
        {
            if (_instance == null)
                _instance = new ContractorBusiness();
            return _instance;
        }

        /// <summary>
        /// Retrieves the instance.
        /// </summary>
        /// <param name="isFake">if set to <c>true</c> [is fake].</param>
        /// <returns></returns>
        public static ContractorBusiness RetrieveInstance(bool isFake)
        {
            if (_instance == null)
                _instance = new ContractorBusiness(isFake);
            return _instance;
        }
        #endregion

        #region CUD
        /// <summary>
        /// Updates the specified contractor.
        /// </summary>
        /// <param name="contractor">The contractor.</param>
        public void Update(Contractor contractor)
        {
            if (contractor == null)
            {
                throw new MockException("Contractor is null");
            }
            if (!_contractorDataAccess.Exist(contractor.ContractorId))
            {
                throw new MockException("Contractor was not existed", "Business");
            }
            User user = contractor.User;
            if (user == null)
            {
                throw new MockException("User is null", "Business");
            }
            if (!_userDataAccess.Exist(user.UserId))
            {
                throw new MockException("User was not existed", "Business");
            }
            Role role = contractor.User.Role;
            if (role == null)
            {
                throw new MockException("Role is null", "Business");
            }
            if (!_roleDataAccess.Exist(role.RoleId))
            {
                throw new MockException("Role was not existed", "Business");
            }
            if (String.IsNullOrEmpty(contractor.FirstName))
            {
                throw new MockException("Firstname is required", "Business");
            }
            string lastName = contractor.LastName;
            lastName = lastName.Trim();
            if (String.IsNullOrEmpty(contractor.LastName) || lastName.IndexOf(" ", StringComparison.CurrentCulture) != -1)
            {
                throw new MockException("Lastname must be a word", "Business");
            }
            _contractorDataAccess.Update(contractor, true);
        }

        #endregion

        #region R
        /// <summary>
        /// Retrieves all contractors.
        /// </summary>
        /// <returns></returns>
        public Collection<Contractor> RetrieveAllContractors()
        {
            return _contractorDataAccess.RetrieveAllContractors();
        }

        /// <summary>
        /// Gets the name of the by user.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <returns></returns>
        public Contractor GetByUserName(string userName)
        {
            if (userName == null)
                return null;
            return _contractorDataAccess.GetByUserName(userName);
        }

        /// <summary>
        /// Gets the by consultant id.
        /// </summary>
        /// <param name="consultantId">The consultant id.</param>
        /// <returns></returns>
        public Collection<Contractor> GetByConsultantId(object consultantId)
        {
            return _contractorDataAccess.GetByConsultantId(consultantId);
        }

        /// <summary>
        /// Gets the by id.
        /// </summary>
        /// <param name="contractorId">The contractor id.</param>
        /// <returns></returns>
        public Contractor GetById(object contractorId)
        {
            return _contractorDataAccess.GetById(contractorId);
        }

        /// <summary>
        /// Gets the by filter.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <param name="email">The email.</param>
        /// <param name="firstName">The first name.</param>
        /// <param name="lastName">The last name.</param>
        /// <param name="isActive">The is active.</param>
        /// <param name="consultantId">The consultant id.</param>
        /// <returns></returns>
        public Collection<Contractor> GetByFilter(object userName, object email, object firstName, object lastName, object isActive, object consultantId)
        {
            return _contractorDataAccess.GetByFilter(userName, email, firstName, lastName, isActive, consultantId);
        }
        #endregion
    }
}
